// 参考 lodash 中 throttle 函数实现的 TypeScript 版本，并将其抽离为独立函数
// 确保一个函数在一定时间间隔内只执行一次。即使在这段时间内多次调用该函数，也只有一次生效。

/**可接受的配置项 */
type ThrottleOptions = {
  /**是否允许立即调用函数，默认true */
  leading?: boolean;
  /**是否允许在时间间隔结束后再调用一次函数，默认true */
  trailing?: boolean;
};

/**
 * 节流函数
 * @param func 执行函数
 * @param wait 间隔时长（毫秒）
 * @param options 可接受的配置项
 * @returns
 */
function throttle(func: Function, wait: number, options: ThrottleOptions = {}) {
  let context: any, args: any, result: any;
  let timeout: NodeJS.Timeout | null = null;
  let previous = 0;
  const { leading = true, trailing = true } = options;

  function later() {
    previous = leading ? Date.now() : 0;
    timeout = null;
    result = func.apply(context, args);
    if (!timeout) context = args = null;
  }

  return function (this: any, ...throttledArgs: any[]) {
    const now = Date.now();
    if (!previous && !leading) previous = now;
    const remaining = wait - (now - previous);
    context = this;
    args = throttledArgs;
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = now;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    } else if (!timeout && trailing) {
      timeout = setTimeout(later, remaining);
    }
    return result;
  };
}

export default throttle;
